﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Domain.ActiveDirectory.Model
{
    public class User : IActiveDirectoryObject
    {
        private IEnumerable<string> _groups;
        private string _completeName;
        private string _userName;
        private string _email;
        private string _title;
        private bool _active;

        public string DistinguishedName { get; set; }

        public User()
        {
            _completeName = "";
            _userName = "";
            _email = "";
            _title = "";
            _active = false;
            _groups = new string[0];
        }

        public string CompleteName 
        {
            get { return _completeName; }
            set { _completeName = value; }
        } // cn

        public string Username 
        { 
            get { return _userName; }
            set { _userName = value; }
        } // sAMAccountName

        public string Email
        {
            get { return _email;  }
            set { _email = value;  }
        } // userPrincipalName

        public string Title 
        {
            get { return _title; }
            set { _title = value;  }
        } // title

        public bool IsActive
        { 
            get { return _active; }
            set { _active = value;  }
        }
        
        public IEnumerable<string> GroupNames 
        { 
            get { return _groups; }
        } // memberOf

        public void SetGroups(IEnumerable<string> groupList)
        { _groups = groupList; }


        public override bool Equals(object obj)
        {
            bool isEqual = false;
            if (obj != null)
            {
                User other = obj as User;
                isEqual = (this.CompleteName == other.CompleteName)
                && (this.Username == other.Username)
                && (this.Email == other.Email)
                && (this.Title == other.Title)
                && (this.IsActive == other.IsActive)
                && (hasEqualGroups(this.GroupNames, other.GroupNames));
            }
            return isEqual;
        }

        private bool hasEqualGroups(IEnumerable<string> a, IEnumerable<string> b)
        {
            bool hasEqualGroups = true;
            for (int i = 0; i < a.Count(); i++)
            {
                if (!a.Contains(b.ElementAt(i)))
                {
                    hasEqualGroups = false;
                }
            }
            return hasEqualGroups;
        }

        public override int GetHashCode()
        {
            int hash = 13;
            hash = (hash * 7) + CompleteName.GetHashCode();
            hash = (hash * 7) + Username.GetHashCode();
            hash = (hash * 7) + Email.GetHashCode();
            hash = (hash * 7) + Title.GetHashCode();
            hash = (hash * 7) + GroupNames.GetHashCode();
            hash = (hash * 7) + IsActive.GetHashCode();
            return hash;
        }

        public override string ToString()
        {
            StringBuilder stringRepresentation = new StringBuilder();
            stringRepresentation.Append("Complete Name: ");
            stringRepresentation.AppendLine(CompleteName);
            stringRepresentation.Append("Username: ");
            stringRepresentation.AppendLine(Username);
            stringRepresentation.Append("Email: ");
            stringRepresentation.AppendLine(Email);
            stringRepresentation.Append("Title: ");
            stringRepresentation.AppendLine(Title);
            stringRepresentation.Append("IsActive: ");
            stringRepresentation.AppendLine(IsActive.ToString());
            stringRepresentation.Append("Groups: ");
            foreach (string groupName in GroupNames)
            {
                stringRepresentation.Append(groupName);
                if (groupName != GroupNames.Last())
                    stringRepresentation.Append(", ");
            }
            return stringRepresentation.ToString();
        }
    }
}
